# -*- coding: utf-8 -*-
# @Time: 2021/11/6 19:26
# @Author: lijinxi
# @File    : back_search.py
# @desc
import numpy as np
from service_placement import *


# 结合服务放置的优化解法，寻找出最优的资源比率--用于主要VNF放置
def back_search(tolerance=0.02, max_iter=20, low=0.4, high=0.7):
    lower_bound = np.full(shape=(max_iter,), fill_value=low, dtype=np.float64)
    upper_bound = np.full(shape=(max_iter,), fill_value=high, dtype=np.float64)
    _N = 2
    record_acceptance = [0]
    for i in range(max_iter):
        if lower_bound[i] >= upper_bound[i]:
            break
        _sp = ServicePlacement(number_requests=800)
        _sp.initialize_decision_variables()
        _sp.initialize_requests()
        alpha = (lower_bound[i] + upper_bound[i]) / 2.0
        _sp.primary_placement_stage(alpha=alpha)
        _sp.backup_placement_stage(beta=1.0 - alpha)
        acceptance = _sp.model.objVal / 200.0
        print("=" * 25, alpha, acceptance)
        # 计算r', 实际上总是可以回溯到, 不需要重复计算
        _acceptance = record_acceptance[-1]
        if acceptance > _acceptance + tolerance:
            lower_bound[i + 1] = alpha
            # 更新上界值, 保持不变
            upper_bound[i + 1] = upper_bound[i]
            record_acceptance.append(acceptance)
        elif acceptance < _acceptance - tolerance:
            lower_bound[i + 1] = lower_bound[i + 1 - _N]
            upper_bound[i + 1] = alpha
            record_acceptance.append(record_acceptance[-_N])  # N=2
        else:
            print(f"stopped at {i}.")
            return _sp.primary_placement, _sp.backup_placement, _sp.admitted_requests


if __name__ == '__main__':
    print(back_search())
